package org.greatlogic.gwtfilereaderwidget.client.itunes;

import com.google.gwt.xml.client.Element;
import java.util.LinkedHashSet;
import java.util.TreeMap;
import org.greatlogic.gwtfilereaderwidget.client.itunes.ITunesEnums.ETrackKeyType;

public class Playlist implements IHasKeyAndValueEntries, Comparable<Playlist> {
//--------------------------------------------------------------------------------------------------
private long                                _id;
private TreeMap<ETrackKeyType, KeyAndValueEntry> _keyAndValueEntryMap;
private ITunesLibrary                       _library;
private String                              _name;
private LinkedHashSet<Track>                _trackSet;
//--------------------------------------------------------------------------------------------------
/**
 * @param playlistDictElement The "dict" node for a playlist.
 */
Playlist(final ITunesLibrary library, final Element playlistDictElement) throws ITunesException {
  _library = library;
  _keyAndValueEntryMap = new TreeMap<ITunesEnums.ETrackKeyType, KeyAndValueEntry>();
  _trackSet = new LinkedHashSet<Track>();
  KeyAndValueEntry.createFromKeyAndValueParentNode(this, playlistDictElement);
} // Playlist()
//--------------------------------------------------------------------------------------------------
@Override
public void addKeyAndValueEntry(final KeyAndValueEntry keyAndValueEntry) {
  _keyAndValueEntryMap.put(keyAndValueEntry.getKeyType(), keyAndValueEntry);
  switch (keyAndValueEntry.getKeyType()) {
    case Name:
      _name = keyAndValueEntry.getValueAsString();
      break;
    case PlaylistID:
      _id = keyAndValueEntry.getValueAsLong();
      break;
    default:
      break;
  }
} // addKeyAndValue()
//--------------------------------------------------------------------------------------------------
@Override
public int compareTo(final Playlist otherPlaylist) {
  return _name.compareTo(otherPlaylist._name);
} // compareTo()
//--------------------------------------------------------------------------------------------------
void addTrack(final int trackID) {
  Track track = _library.getTrackByTrackID(trackID);
  if (track != null) {
    _trackSet.add(track);
  }
} // addTrack()
//--------------------------------------------------------------------------------------------------
public long getID() {
  return _id;
} // getID()
//--------------------------------------------------------------------------------------------------
@Override
public KeyAndValueEntry getKeyAndValueEntry(final ETrackKeyType keyType) {
  KeyAndValueEntry result = _keyAndValueEntryMap.get(keyType);
  return result == null ? KeyAndValueEntry.EmptyKeyAndValueEntry : result;
} // getKeyAndValueEntry()
//--------------------------------------------------------------------------------------------------
@Override
public TreeMap<ETrackKeyType, KeyAndValueEntry> getKeyAndValueEntryMap() {
  return _keyAndValueEntryMap;
} // getKeyAndValueEntryMap()
//--------------------------------------------------------------------------------------------------
public String getName() {
  return _name;
} // getName()
//--------------------------------------------------------------------------------------------------
public LinkedHashSet<Track> getTrackSet() {
  return _trackSet;
} // getTrackSet()
//--------------------------------------------------------------------------------------------------
StringBuilder getXML(final StringBuilder sb, final String xmlIndent, final String endOfLineString) {
  StringBuilder result;
  if (sb == null) {
    result = new StringBuilder(1000);
  }
  else {
    result = sb;
    result.setLength(0);
  }
  String xmlIndent2 = xmlIndent + xmlIndent;
  String xmlIndent3 = xmlIndent2 + xmlIndent;
  String xmlIndent4 = xmlIndent3 + xmlIndent;
  String xmlIndent5 = xmlIndent4 + xmlIndent;
  result.append(xmlIndent2).append("<dict>").append(endOfLineString);
  for (KeyAndValueEntry keyAndValueEntry : _keyAndValueEntryMap.values()) {
    result.append(xmlIndent3).append(keyAndValueEntry.getXML()).append(endOfLineString);
  }
  result.append(xmlIndent3).append("<key>Playlist Items</key>").append(endOfLineString);
  result.append(xmlIndent3).append("<array>").append(endOfLineString);
  for (Track track : _trackSet) {
    result.append(xmlIndent4).append("<dict>").append(endOfLineString);
    result.append(xmlIndent5).append("<key>Track ID</key>");
    result.append("<integer>").append(track.getTrackID()).append("</integer>").append(endOfLineString);
    result.append(xmlIndent4).append("</dict>").append(endOfLineString);
  }
  result.append(xmlIndent3).append("</array>").append(endOfLineString);
  result.append(xmlIndent2).append("</dict>").append(endOfLineString);
  return result;
} // getXML()
//--------------------------------------------------------------------------------------------------
/**
 * @param keyType This should be ETrackKeyType.PlaylistItems.
 * @param arrayElement The "array" element that contains the playlist entries.
 * Example:
 *   <key>Playlist Items</key>
 *   <array>
 *     <dict>
 *       <key>Track ID</key><integer>1030</integer>
 *     </dict>
 *     <dict>
 *       <key>Track ID</key><integer>5728</integer>
 *     </dict>
 *   </array>
 */
@Override
public boolean processArray(final ETrackKeyType keyType, final Element arrayElement)
  throws ITunesException {
  boolean result = keyType == ETrackKeyType.PlaylistItems;
  if (result) {
    Element dictElement = ITunesUtil.getFirstChildElement(arrayElement, "dict");
    while (dictElement != null) {
      Element trackIDElement = ITunesUtil.getFirstChildElement(dictElement, "key", "Track ID",
                                                               "Track ID 'key' element expected");
      trackIDElement = ITunesUtil.getNextSiblingElement(trackIDElement);
      ITunesUtil.validateElementName(trackIDElement, "integer",
                                     "Track ID 'integer' element expected");
      int trackID = ITunesUtil.stringToInt(ITunesUtil.getElementValue(trackIDElement), -1);
      addTrack(trackID);
      dictElement = ITunesUtil.getNextSiblingElement(dictElement, "dict");
    }
  }
  return result;
} // processArray()
//--------------------------------------------------------------------------------------------------
@Override
public String toString() {
  return _name + " (Number of tracks:" + _trackSet.size() + ")";
} // toString()
//--------------------------------------------------------------------------------------------------
}